package com.core.util;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Properties;
import java.util.ResourceBundle;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.faces.context.FacesContext;
import javax.mail.BodyPart;
import javax.mail.Message;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.servlet.http.HttpSession;

import com.core.constants.Constants;


public class Util {


	private static ResourceBundle bundle;

	public static final String fileSeparator = "/";

	public static final String backSlash = "\\";

	public static final String spcae = " ";

	public static final String dash = "-";

	public static final String ATOLL = "Atoll.xls";

	public static final String ATOLL_FILE = "PeriodicRunReults.tsv";

	public static ResourceBundle getBundle() {
		if (bundle == null) {
			FacesContext context = FacesContext.getCurrentInstance();
			bundle = context.getApplication().getResourceBundle(context, "config");
		}
		return bundle;
	}

	public static String getOSName() {
		return System.getProperty("os.name");
	}

	public static Boolean isWindows() {
		return getOSName().startsWith("Windows");
	}

	public static String getBundleValue(String key) {
		return getBundle().getString(key);
	}

	public static Double round(Double number, int precision) {
		int prec = 10 * precision;
		return Math.floor(number * prec + .5) / prec;
	}

	public static String getJNDIContextName() {
		String result = null;
		if (isJBossServer()) {
			result = Constants.JNDI_CONTEXT_NAME_JBOSS;
		} else if (isTomcatServer()) {
			result = Constants.JNDI_CONTEXT_NAME_TOMCAT;
		}
		return result;
	}

	public static Boolean isTomcatServer() {
		return getBundleValue("applicationServer").equals("2");// Constants.APPLICATION_SERVER.equals(2);
	}

	public static Boolean isJBossServer() {
		return getBundleValue("applicationServer").equals("1");// Constants.APPLICATION_SERVER.equals(1);
	}

	public static String getResourceFolderPath() {
		return ((String) getJNDIValue("resourcsFolder")) + getFileSeparator();
	}

	public static String getAtollFolderPath() {
		return ((String) getJNDIValue("AtollFolder")) + getFileSeparator();
	}

	public static String getAtoll2GPath() {
		return ((String) getJNDIValue("Atoll2G")) + getFileSeparator();
	}

	public static String getAtoll3GPath() {
		return ((String) getJNDIValue("Atoll3G")) + getFileSeparator();
	}

	public static String getAtollBsc() {
		return ((String) getJNDIValue("bsc"));
	}
	public static String getIP() {
		return ((String) getJNDIValue("atollIP"));
	}

	public static String getAtollRnc() {
		return ((String) getJNDIValue("rnc"));
	}

	public static String getAtollTrace() {
		return ((String) getJNDIValue("trace"));
	}

	public static String getSendMailServer() {
		return ((String) getJNDIValue("mailServer"));
	}

	public static String getSendMailEmail() {
		return ((String) getJNDIValue("mailEmail"));
	}

	public static String getSendMailEmailPassword() {
		return ((String) getJNDIValue("mailEmailPassword"));
	}

	public static String getSendMailPort() {
		return ((String) getJNDIValue("mailPort"));
	}

	public static String getSendMailEmailHeader() {
		return ((String) getJNDIValue("mailHeader"));
	}

	public static String getFileSeparator() {
		return System.getProperty("file.separator");
	}

	public static Object getJNDIValue(String name) {
		String value = null;
		try {
			Context initCtx = new InitialContext();
			if (isJBossServer()) {
				value = (String) initCtx.lookup(name); // jboss
			} else if (isTomcatServer()) {
				Context envCtx = (Context) initCtx.lookup(Constants.JNDI_CONTEXT_NAME_TOMCAT); // tomcat
				value = (String) envCtx.lookup(name);
			}
		} catch (NamingException e) {
			e.printStackTrace();
		}
		return value;
	}

	public static double round(double Rval, int Rpl) {
		double p = (double) Math.pow(10, Rpl);
		Rval = Rval * p;
		double tmp = Math.round(Rval);
		return (double) tmp / p;
	}

	public static Boolean isStringContains(String text, String innerText) {
		return (text != null && (text.contains(innerText)));
	}

	public static String hex(byte[] array) {
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < array.length; ++i) {
			sb.append(Integer.toHexString((array[i] & 0xFF) | 0x100).substring(1, 3));
		}
		return sb.toString();
	}

	public static String md5pwd(String message, String salt) {
		try {
			MessageDigest md = MessageDigest.getInstance("MD5");
			String msg = new StringBuffer(message).append("{").append(salt).append("}").toString();
			return hex(md.digest(msg.getBytes("UTF-8")));
		} catch (NoSuchAlgorithmException e) {
		} catch (UnsupportedEncodingException e) {
		}
		return null;
	}

	public static String formatDateTime(Date date) {
		DateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
		return dateFormat.format(date);
	}

	public static String formatDate(Date date) {
		DateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
		return dateFormat.format(date);
	}

	public static String formatDate2(Date date) {
		DateFormat dateFormat = new SimpleDateFormat("dd-MMM-yyyy");
		return dateFormat.format(date);
	}

	public static String formatDate3(Date date) {
		DateFormat dateFormat = new SimpleDateFormat("dd-MMM-yy");
		return dateFormat.format(date);
	}
	
	public static String formatDate4(Date date) {
		DateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
		return dateFormat.format(date);
	}

	public static Boolean validateReqularExpression(String reqExpression, String value) {
		Pattern pattern = Pattern.compile(reqExpression);
		Matcher fit = pattern.matcher(value);
		return fit.matches();
	}

	public static boolean isNumeric(String obj) {
		return obj.matches("(\\d+)");
	}

	public static boolean isIndexExist(List<?> list, int index) {
		try {
			return null != list.get(index);
		} catch (IndexOutOfBoundsException e) {
			return false;
		}
	}

	public static String getFileExtention(String fileName) {
		String fileExt = "";
		Integer index = fileName.lastIndexOf(".");
		if (index > 0) {
			fileExt = fileName.substring(index + 1, fileName.length());
		}
		return fileExt;
	}

	public static Long getUserId() {
		Long userId = 0L;
		try {
			HttpSession httpSession = (HttpSession) FacesContext.getCurrentInstance().getExternalContext().getSession(true);
			Object userIdNumber = httpSession.getAttribute("userId");
			userId = (Long) userIdNumber;
		} catch (Exception e) {
			System.out.println("No user's login");
		}
		return userId;
	}

	public static List<Long> convertStringIdListToLongIdList(List<String> stringIdList) {
		List<Long> longIdList = new ArrayList<Long>();
		if (Utils.isNotEmpty(stringIdList)) {
			for (String id : stringIdList) {
				longIdList.add(Long.valueOf(id));
			}
		}
		return longIdList;
	}


	public static Double getDecimalDegree(String degree) {
		try {
			Double decimal = -1D;
			if (Utils.isNotEmpty(degree)) {
				String[] degreeArr = degree.split("\\-");
				if (Utils.isNotEmpty(degreeArr) && degreeArr.length > 0) {
					decimal = Double.valueOf(degreeArr[0]);
					if (degreeArr.length > 1) {
						decimal += Double.valueOf(degreeArr[1]) / 60;
						if (degreeArr.length > 2) {
							decimal += Double.valueOf(degreeArr[2]) / 3600;
						}
					}
				}
			}
			return decimal;
		} catch (Exception e) {
			return -1D;
		}
	}

	public static String getDDMMSS(Double decimal) {
		String DDMMSS = "";
		if (Utils.isNotEmpty(DDMMSS)) {
			String[] DDMMSSArr = decimal.toString().split("\\.");
			if (Utils.isNotEmpty(DDMMSSArr) && DDMMSSArr.length > 0) {
				DDMMSS = DDMMSSArr[0];
				if (DDMMSSArr.length > 1) {
					double dd = Double.valueOf(DDMMSSArr[1]) / Math.pow(10, DDMMSSArr[1].length());
					decimal = dd * 60D;
					DDMMSSArr = decimal.toString().split("\\.");
					DDMMSS += "-";
					DDMMSS += DDMMSSArr[0];
					if (DDMMSSArr.length > 1) {
						double dd2 = Double.valueOf(DDMMSSArr[1]) / Math.pow(10, DDMMSSArr[1].length());
						decimal = dd2 * 60D;
						DDMMSS += "-";
						DDMMSS += Math.round(decimal);
					}
				}
			}
		}
		return DDMMSS;
	}

	/* :: lat1, lon1 = Latitude and Longitude of point 1 (in decimal degrees) : */
	/* :: lat2, lon2 = Latitude and Longitude of point 2 (in decimal degrees) : */
	/* :: unit = the unit you desire for results : */
	/* :: where: 'M' is statute miles : */
	/* :: 'K' is kilometers (default) : */
	/* :: 'N' is nautical miles : */
	public static double distance(double lat1, double lon1, double lat2, double lon2, char unit) {
		double theta = lon1 - lon2;
		double dist = Math.sin(deg2rad(lat1)) * Math.sin(deg2rad(lat2)) + Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2))
				* Math.cos(deg2rad(theta));
		dist = Math.acos(dist);
		dist = rad2deg(dist);
		dist = dist * 60 * 1.1515;
		if (unit == 'K') {
			dist = dist * 1.609344;
		} else if (unit == 'N') {
			dist = dist * 0.8684;
		}
		return (dist);
	}

	/* ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: */
	/* :: This function converts decimal degrees to radians : */
	/* ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: */
	private static double deg2rad(double deg) {
		return (deg * Math.PI / 180.0);
	}

	/* ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: */
	/* :: This function converts radians to decimal degrees : */
	/* ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: */
	private static double rad2deg(double rad) {
		return (rad * 180.0 / Math.PI);
	}

	/**
	 * IQ functions
	 */
	public static String getIQDatabaseUrl() {
		return getJNDIValue("IQ_DATABASE_URL").toString();
	}

	public static String getIQDatabaseUsername() {
		return getJNDIValue("IQ_DATABASE_USERNAME").toString();
	}

	public static String getIQDatabasePassword() {
		return getJNDIValue("IQ_DATABASE_PASSWORD").toString();
	}

	public static String getIQDatabaseTableName() {
		return getJNDIValue("IQ_DATABASE_TABLE_NAME").toString();
	}

	public static Boolean isLdapActive() {
		String lDapValue = getJNDIValue("ldap").toString();
		if (lDapValue != null && lDapValue.equals("true")) {
			return true;
		} else {
			return false;
		}
	}

	public static String enc(String S) {
		char[] Enc = { 'N', 'T', 'G' };
		if (S == null) {
			return "";
		}
		int j = 0;
		char[] C = S.toCharArray();
		for (int i = 0; i < C.length; i++) {
			C[i] ^= Enc[j];
			j++;
			if (j > 2) {
				j = 0;
			}
			// System.out.print("" + C);
		}
		// System.out.println("Enc mothod");
		return String.valueOf(C);
	}

	public static Long getDefaultViolatedTime() {
		return new Date(1990, 01, 01, 12, 00, 00).getTime();
	}

	public static void writeToViolatedFile(String val) {
		try {
			String fileName = System.getProperty("user.dir") + System.getProperty("file.separator") + "violatedDate.txt";
			FileWriter fstream = new FileWriter(fileName);
			BufferedWriter out = new BufferedWriter(fstream);
			out.write(Util.enc(val));
			out.close();
		} catch (Exception e) {
			System.out.println("DateViolatedFiled Not Found");
		}
	}

	public static Date getViolatedDate() {
		String fileName = System.getProperty("user.dir") + System.getProperty("file.separator") + "violatedDate.txt";
		Date result = null;
		try {
			FileInputStream fis = new FileInputStream(fileName);
			DataInputStream in = new DataInputStream(fis);
			BufferedReader br = new BufferedReader(new InputStreamReader(in));
			String readLine = "";
			String tempString;
			while ((tempString = br.readLine()) != null) {
				readLine += tempString;
			}
			readLine = Util.enc(readLine);
			result = new Date(new Long(readLine));
		} catch (Exception e) {
			System.out.println("violated text not found");
		}
		return result;
	}

	public static Integer getLicenseCheckTimer() {
		Integer x=(Integer)getJNDIValue("licenseCheckTimer");
		
		return  x;
	}
	
	public static void SendEmail(String to, String from, String subject, String body, String cc, String bcc) throws Exception {
		// String smtpServer = "tormail.ntgclarity.com";
		String smtpServer = Util.getSendMailServer();
		Session session = initConfgration(smtpServer);
		// -- Create a new message --
		Message msg = new MimeMessage(session);
		// -- Set the FROM and TO fields --
		if (from != null) {
			msg.setFrom(new InternetAddress(from));
		} else {
			String mailEmail = Util.getSendMailEmail();
			msg.setFrom(new InternetAddress(mailEmail));
		}
		if (to != null) {
			msg.setRecipients(Message.RecipientType.TO, InternetAddress.parse(to, false));
		}
		// -- We could include CC recipients too --
		if (cc != null && cc != null) {
			msg.setRecipients(Message.RecipientType.BCC, InternetAddress.parse(cc, false));
		}
		if (bcc != null && bcc != null) {
			msg.setRecipients(Message.RecipientType.BCC, InternetAddress.parse(bcc, false));
		}
		// -- Set the subject and body text --
		msg.setSubject(subject);
		/********************************/
		BodyPart messageBodyPart = new MimeBodyPart();
		messageBodyPart.setContent(body, "text/html;charset=UTF-8");
		// Create a related multi-part to combine the parts
		MimeMultipart multipart = new MimeMultipart("related");
		multipart.addBodyPart(messageBodyPart);
		// Associate multi-part with message
		msg.setContent(multipart);
		/********************************/
		// -- Set some other header information --
		String header = Util.getSendMailEmailHeader();
		msg.setHeader("X-Mailer", header);
		msg.setSentDate(new Date());
		// -- Send the message --
		send(msg, session);
	}
	private static Session initConfgration(String smtpServer) {
		Properties props = System.getProperties();
		// -- Attaching to default Session, or we could start a new one --
		props.put("mail.smtp.host", smtpServer);
		String port = Util.getSendMailPort();
		props.put("mail.smtp.port", port);// must get from server properties
		return Session.getDefaultInstance(props, null);
	}

	private static void send(Message msg, Session session) throws Exception {
		Transport tr = session.getTransport("smtp");
		String mailServer = Util.getSendMailServer();
		String mailEmail = Util.getSendMailEmail();
		String mailEmailPassword = Util.getSendMailEmailPassword();
		tr.connect(mailServer, mailEmail, mailEmailPassword);
		tr.sendMessage(msg, msg.getAllRecipients());
		tr.close();
	}

}
